#!/bin/bash

# create temp file
: ${TMPDIR:=/tmp/HPCKit}
mkdir -p $TMPDIR
save_mask=$(umask)
trap 'umask "${save_mask}"' EXIT
umask 077
temp_trace_file=$(mktemp "${TMPDIR}/XXXXXXXXXXXXXXXXXX")
if [ $? -ne 0 ]; then
    exit 1
fi

current_dir=$(cd $(dirname $0) && command pwd -P)
kit_root=$(dirname $current_dir)
current_version=$(basename $current_dir)

check_trace_file() {
    local trace_file="$1"
    if [ ! -e "$trace_file" ]; then
        echo ".INSTALL_TRACE file corrupted, HPCKit cannot be removed."
        exit 1
    fi
}

del_empty_dirs() {
    local dir_path="$1"
    if [ -z "$(ls -A $dir_path)" ]; then
        rm -r $dir_path
        return $?
    fi

    local ret=0
    local dirs=$(find $dir_path -mindepth 1 -type d | sort -r)
    for dir in $dirs; do
        del_empty_dirs $dir
        if [[ "$?" -ne 0 ]];then
            ret=1
        fi
    done
    return $ret
}

get_comps_path() {
    local comps=`find "$1" -maxdepth 1 -mindepth 1 -type d`
    echo "$comps"
}

spin () {
    echo -n "$1"
    chars="| / – \\"
    delay=0.1
    while true; do
        for char in $chars; do
            echo -ne $char
            sleep $delay
            echo -ne '\b'
        done
    done
}

# del file or dir
del_path () {
    local comp_file="$1"

    # trim \r at end of line
    local file_path=$(echo "$comp_file" | sed -e 's/\r//g')

    # 0. del when dir is empty
    if [ -d "$file_path" ] && [ ! -L "$file_path" ]; then
        del_empty_dirs $file_path
        if [[ "$?" -ne 0 ]];then
            echo "rm $file_path fail"
            echo "$file_path" >> $temp_trace_file
        fi
        return
    fi

    # 1. del file
    if [ -e "$file_path" ]; then
        # try del file, record in temp_trace_file when failed
        if ! rm -rf "$file_path" 2>/dev/null; then
            echo "rm $file_path fail"
            echo "$file_path" >> $temp_trace_file
        fi
    else
        # file may be soft link and not exist
        rm -rf "$file_path" 2>/dev/null
    fi
}

# delete all files of component in trace_file
del_comp() {
    local comp_root="$1"
    local trace_file="$2"
    local comp_files=`cat $trace_file | grep $comp_root | sort -r`
    local comp_name=$(basename $comp_root)
    spin "* Uninstall $comp_name " &
    for comp_file in $comp_files; do
        del_path $comp_file
    done

    kill $!
    printf "\r* Uninstall $comp_name success\n"
}

del_root() {
    local root_path="$1"
    local trace_file="$2"
    local uninstall_file="$root_path/uninstall.sh"
    local root_files=$(cat $trace_file | grep -E "$root_path/.+/" -v)
    for root_file in $root_files; do
        if [[ ! "$root_file" == "$uninstall_file" ]]; then
            del_path $root_file
        fi
    done

    # remove trace file
    if [ -s "$temp_trace_file" ]; then
        mv "$temp_trace_file" "$trace_file"
    else
        rm -rf $trace_file
    fi
    del_path $root_path

    if [ ! -z "$(find $current_dir -type f | grep -v $trace_file | grep -v $uninstall_file)" ]; then
        echo ""
        echo "These files not belong to HPCKit, please remove them manually."
        find $current_dir -type f | grep -v $trace_file | grep -v $uninstall_file
    else
        echo "Uninstall HPCKit Success."
    fi
}

uninstall() {
    cd $current_dir
    echo "Start uninstall HPCKit..."
    local trace_file_name=".INSTALL_TRACE"
    local trace_file=$current_dir/$trace_file_name
    check_trace_file $trace_file
    local temp_file_name=".TMP_INSTALL_TRACE"
    local temp_file="$current_dir/$temp_file_name"
    while IFS= read -r line; do
        tmp_line="$current_dir/$line"
        echo "$tmp_line" >> "$temp_file"
    done < "$trace_file"
    mv $temp_file $trace_file
    local comps_path=`get_comps_path $current_dir`
    for comp_path in $comps_path; do
        del_comp $comp_path $trace_file
    done
    del_root $current_dir $trace_file
}

uninstall

# create temp file
temp_script=$(mktemp "${TMPDIR}/XXXXXXXXXXXXXXXXXX")
if [ $? -ne 0 ]; then
    exit 1
fi
chmod u+x $temp_script

# 将卸载逻辑和删除命令写入临时脚本
cat << 'EOF' > "$temp_script"

#!/bin/bash
kit_root=$(dirname $current_dir)
current_version=$(basename $current_dir)
cd $kit_root

: ${TMPDIR:=/tmp/HPCKit}
trap '[ -n "${TMPDIR}" ] && rm -rf "${TMPDIR}"' EXIT

redirect_latest()
{
    # remove latest dir
    rm -rf "$kit_root/latest" 2>/dev/null

    # get all subdirectories
    local subdirectories=($(find "$kit_root" -maxdepth 1 -mindepth 1 -type d))

    if [[ -z ${subdirectories[@]} ]]; then
        return
    fi

    # Filter out subdirectories with similar date formats
    local filtered_directories=()
    for dir in "${subdirectories[@]}"; do
        local dir_name=$(basename "$dir")
        if [[ "$dir_name" =~ ^[0-9]{2}\.[0-9]{1,2}\.[0-9]{1,2}$ ]]; then
            filtered_directories+=("$dir")
        fi
    done

    # Find the subdirectory with the closest date
    local latest_directory=""
    local latest_date="00000000"
    for dir in "${filtered_directories[@]}"; do
        local dir_name=$(basename "$dir")

        local year=$(echo "$dir_name" | awk -F'.' '{print $1}')
        local month=$(echo "$dir_name" | awk -F'.' '{print $2}')
        local day=$(echo "$dir_name" | awk -F'.' '{print $3}')

        # date format YYYYMMDD
        local current_date=$(printf "%04d%02d%02d" "$year" "$month" "$day")

        if [ "$current_date" -gt "$latest_date" ]; then
            latest_date="$current_date"
            latest_directory="$dir"
        fi
    done

    # create symbolic link latest
    if [ -n "$latest_directory" ]; then
        ln -sfn "$latest_directory" "$kit_root/latest"
    fi
}

del_install_history() {
    local _kit_version=$(basename $current_dir)
    local _kit_root=$(dirname "$(dirname $current_dir)")
    local _install_history_file="$HOME/.HPCKit/install_history/$_kit_version"
    # remove install history
    if [ -e ${_install_history_file} ]; then
        _kit_root_escape=$(echo "$_kit_root" | sed 's/\//\\\//g')
        sed -i /${_kit_root_escape}$/d ${_install_history_file}
    fi
}

del_empty_dir() {
    local dir_path="$1"
    if [ -d "$dir_path" ] && [ -z "$(ls -A "$dir_path")" ]; then
        rm -rf $dir_path 2>/dev/null
    fi
}

rm -rf $current_dir/uninstall.sh

del_empty_dir $current_dir
redirect_latest
del_install_history
del_empty_dir $kit_root
EOF

# add current_dir path to temp_script
sed -i "/\#!\/bin\/bash/a current_dir=$current_dir" $temp_script

setsid sh $temp_script &